~ chicken-core (chicken-5) /manual/Cross development


  1[[tags: manual]]
  2[[toc:]]
  3
  4
  5== Cross Development
  6
  7Since CHICKEN generates C code, it is relatively easy to create
  8programs and libraries for a different architecture than the one the
  9compiler is executing on, a process commonly called ''cross
 10compiling''. Basically you can simply compile Scheme code to C and
 11then invoke your target-specific cross compiler.  To automate the
 12process of invoking the correct C compiler with the correct settings
 13and to simplify the use of extensions, CHICKEN can be built in a
 14special "cross-compilation" mode.
 15
 16Note: in the following text we refer to the "target" as being the
 17platform on which the software is intended to run in the end. We use
 18the term "host" as the system that builds this software. Others use a
 19different nomenclature or switch the meaning of the words.
 20
 21=== Preparations
 22
 23Make sure you have a cross-toolchain in your {{PATH}}. In this
 24example, a Linux system is used to generate binaries for an ARM based
 25embedded system.
 26
 27==== Building the target libraries
 28
 29First you need a version of the runtime system ({{libchicken}}),
 30compiled for the target system. Obtain and unpack a tarball of the
 31CHICKEN sources, or check out the code from the official code
 32repository, then build the libraries and necessary development files:
 33
 34 make ARCH= \
 35     PREFIX=/usr \
 36     PLATFORM=linux \
 37     HOSTSYSTEM=arm-none-linux-gnueabi \
 38     DESTDIR=$HOME/target \
 39     TARGET_FEATURES="-no-feature x86 -feature arm" \
 40     install
 41
 42This will build CHICKEN and install it in {{~/target}}, which we use
 43as a temporary place to store the target files. A few things to note:
 44
 45* {{ARCH}} is empty, since we don't want the build process to detect the architecture (since the target-architecture is likely to be different).  If you know the right string to represent target architecture, you can set {{ARCH}} with that value.  This string is passed to the {{-arch}} compiler and linker option for ios and sometimes conditionally checked in platform-specific makefiles)
 46* {{PREFIX}} gives the prefix ''on the target system'', under which the
 47libraries will finally be installed. In this case it will be {{/usr/lib}}.
 48
 49* {{PLATFORM}} determines the target platform. It must be one of the officially
 50supported platforms CHICKEN runs on. Note that it actually refer to the extension of a dedicated Makefile (`Makefile.linux` in our case).
 51
 52* {{HOSTSYSTEM}} is an identifier for the target system and will be used as
 53the name prefix of the cross C compiler (in this case {{arm-none-linux-gnueabi-gcc}}).
 54If your cross compiler does not follow this convention, pass {{C_COMPILER}} and
 55{{LIBRARIAN}} to the {{make(1)}} invocation, with the names of the C compiler and
 56{{ar(1)}} tool, respectively.
 57
 58* {{DESTDIR}} holds the directory where the compiled library files will temporarily
 59be installed into.
 60
 61* {{TARGET_FEATURES}} contains extra options to be passed to the target-specific
 62Scheme translator; in this case we disable and enable features so that code like
 63the following will do the right thing when cross-compiled:
 64
 65<enscript hightlight=scheme>
 66(cond-expand
 67  (x86 <do this ...>)
 68  ...)
 69</enscript>
 70
 71* If you obtained the sources from a source-code repository and not
 72from an official release tarball, you will need a {{chicken}}
 73executable to compile the Scheme sources of the runtime system. In
 74this case pass yet another variable to the {{make(1)}} invocation:
 75{{CHICKEN=<where the "chicken" executable is>}}.
 76
 77* You can also put all those variables into a file, say {{config.mk}}
 78and run {{make CONFIG=config.mk}}.
 79
 80You should now have these files on {{~/target}}:
 81
 82 |-- bin
 83 |   |-- chicken
 84 |   |-- chicken-bug
 85 |   |-- chicken-install
 86 |   |-- chicken-profile
 87 |   |-- chicken-status
 88 |   |-- chicken-uninstall
 89 |   |-- csc
 90 |   `-- csi
 91 |-- include
 92 |   |-- chicken-config.h
 93 |   `-- chicken.h
 94 |-- lib
 95 |   |-- chicken
 96 |   |   `-- 9
 97 |   |       :
 98 |   |
 99 |   |-- libchicken.a
100 |   |-- libchicken.so -> libchicken.so.9
101 |   `-- libchicken.so.9
102 `-- share
103     |-- chicken
104     |   |-- doc
105     :   ;   :
106     |   |
107     |   `-- setup.defaults
108     `-- man
109         `-- man1
110             :
111
112You should now transfer {{~/target/usr/lib}} to the target system, and place
113its contents in {{/usr/lib}}. You may want to omit the static library {{libchicken.a}} if the target memory is limited.
114
115==== Building the "cross chicken"
116
117Next, we will build another chicken, one that uses the cross C compiler to
118generate target-specific code that uses the target-specific runtime library
119we have just built.
120
121Again, unpack a CHICKEN release tarball or a source tree and run
122{{make(1)}} once again:
123
124 make PLATFORM=linux \
125     PREFIX=$HOME/cross-chicken \
126     TARGETSYSTEM=arm-none-linux-gnueabi \
127     PROGRAM_PREFIX=arm- \
128     TARGET_PREFIX=$HOME/target/usr \
129     TARGET_RUN_PREFIX=/usr \
130     install
131
132* {{PREFIX}} gives the place where the "cross chicken" should be installed
133into. It is recommended not to install into a standard location (like {{/usr/local}}
134or {{$HOME}}) - some files will conflict with a normal CHICKEN installation.
135
136* {{TARGETSYSTEM}} gives the name-prefix of the cross C compiler and other tools (C++ compiler, librarian (ar) and ressource compiler (for windows)).
137
138* {{PROGRAM_PREFIX}} determines the name-prefix of the CHICKEN tools to be created.
139
140* {{TARGET_PREFIX}} specifies where the target-specific files (libraries and
141headers) are located. This is the location where we installed the runtime
142system into.
143
144* {{TARGET_RUN_PREFIX}} holds the PREFIX that will be effective at runtime
145(so {{libchicken.so}} will be found in {{$TARGET_RUN_PREFIX/lib}}).
146
147* Make sure to use the same version of the CHICKEN sources for the target and
148the cross build.
149
150* If you build the cross chicken from repository sources, the same note
151about the {{CHICKEN}} variable applies as given above.
152
153In {{~/cross-chicken}}, you should find the following:
154
155 |-- bin
156 |   |-- arm-chicken
157 |   |-- arm-chicken-install
158 |   |-- arm-chicken-profile
159 |   |-- arm-chicken-status
160 |   |-- arm-chicken-uninstall
161 |   |-- arm-csc
162 |   `-- arm-csi
163 |-- include
164 |   |-- chicken-config.h
165 |   `-- chicken.h
166 |-- lib
167 |   |-- chicken
168 |   |   `-- 9
169 |   |       :
170 |   |
171 |   |-- libchicken.a
172 |   |-- libchicken.so -> libchicken.so.9
173 |   `-- libchicken.so.9
174 `-- share
175     |-- chicken
176     |   |-- doc
177     :   ;   :
178     |   |
179     |   `-- setup.defaults
180     `-- man
181         `-- man1
182             :
183
184To make sure that the right C compiler is used, we ask {{arm-csc}} to show
185the name of the cross C compiler:
186
187  % ~/cross-chicken/bin/arm-csc -cc-name
188  arm-none-linux-gnueabi-gcc
189
190Looks good.
191
192==== Special notes for Linux to Windows cross development
193
194To cross compile from Linux to Windows, you will need to use a Linux build of MingGW-w64 with you can find in most distribution.
195
196As far as the runtime is concerned, the procedure is the same that what have been shown before, using the platform name {{cross-linux-mingw}}.
197
198The procedure to compile the compiler however require some more care:
199* The platform name is {{linux}} because it is where you want your compiler to run.
200* You have to change {{TARGET_LIBRARIES}} to {{-lm -lws2_32}}.
201* You have to make sure you are pointing to the right toolchain (see next paragraph).
202
203In order to compile the C sources that Chicken will produce you have to make sure that you provide the right toolchain in both runtime and compiler steps.
204
205In most cases, you want to do that by setting {{HOSTSYSTEM}} when building the runtime and {{TARGETSYSTEM}} when building the compiler to something similar to {{x86_64-w64-mingw32}} (check you distribution binaries). For example:
206
207 # build a CHICKEN runtime for windows
208 > make PREFIX=$HOME/target PLATFORM=cross-linux-mingw HOSTSYSTEM=x86_64-w64-mingw32 install
209 > make confclean
210 # build a CHICKEN cross-compiler that uses the runtime above
211 > make PREFIX=$HOME/cross PROGRAM_PREFIX=mingw- TARGET_PREFIX=$HOME/target PLATFORM=linux TARGETSYSTEM=x86_64-w64-mingw32 TARGET_LIBRARIES="-lm -lws2_32" install
212
213If your distribution does not stick to the {{PREFIX-TOOLNAME}} convention you may want to set some following variables (runtime step/compiler step):
214* {{C_COMPILER}}/{{TARGET_C_COMPILER}}
215* {{CXX_COMPILER}}/{{TARGET_CXX_COMPILER}}
216* {{LIBRARIAN}}/{{TARGET_LIBRARIAN}} for {{ar}}
217* {{RC_COMPILER}}/{{TARGET_RC_COMPILER}} for {{windres}}
218
219You may need this trick to pick {{x86_64-w64-mingw32-gcc-posix}} over {{x86_64-w64-mingw32-gcc-win32}} in Debian for example (those correspond to different thread APIs).
220
221=== Using it
222
223==== Compiling simple programs
224
225  % ~/cross-chicken/bin/arm-csc -v hello.scm
226  /home/felix/cross-chicken/arm-cross-chicken/bin/arm-chicken hello.scm -output-file hello.c -quiet
227  arm-none-linux-gnueabi-gcc hello.c -o hello.o -c -fno-strict-aliasing -DHAVE_CHICKEN_CONFIG_H -g -Wall \
228    -Wno-unused -I /home/felix/cross-chicken/arm-chicken/include
229  rm hello.c
230  arm-none-linux-gnueabi-gcc hello.o -o hello -L/home/felix/cross-chicken/arm-chicken/lib  -Wl,-R/usr/lib -lm \
231    -ldl -lchicken
232  rm hello.o
233
234Is it an ARM binary?
235
236  % file hello
237  hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.16, dynamically linked (uses shared libs), not stripped
238
239Yes, looks good.
240
241==== Compiling extensions
242
243By default, the tools that CHICKEN provides to install, list and uninstall
244extensions will operate on both the host and the target repository.
245So running {{arm-chicken-install}} will compile and install the extension 
246for the host system and for the cross-target. To selectively install, uninstall
247or list extensions for either the host or the target system use the
248{{-host}} and {{-target}} options for the tools.
249
250For example, using the mingw-cross-compiler from above, we can create
251a standalone Windows exe file that includes the CHICKEN runtime and all
252egg dependencies.
253
254 # install an egg using the mingw cross compiler above
255 > $HOME/cross/bin/mingw-chicken-install fmt
256 > cat hello.scm
257 (import fmt chicken.platform)
258 (fmt #t "hello world from " (software-type) nl
259      (pretty (features)))
260 # create a standalone exe file with the CHICKEN and fmt statically linked
261 > $HOME/cross/bin/mingw-csc -static hello.scm
262 # hello.exe should now run on Window without any runtime DLL dependencies:
263 > x86_64-w64-mingw32-objdump -p hello.exe | grep "DLL Name"
264    DLL Name: KERNEL32.dll 
265    DLL Name: msvcrt.dll 
266    DLL Name: USER32.dll
267    DLL Name: WS2_32.dll
268 # or using wine
269 > wine hello.exe
270 hello world from windows
271 (#:windows            #:64bit              #:cross-chicken
272  #:ptables            #:dload              #:little-endian
273  #:x86-64             #:gnu                #:mingw32
274  ...)
275
276
277=== "Target-only" extensions
278
279Sometimes an extension will only be compilable for the target platform
280(for example libraries that use system-dependent features). In this
281case you will have to work around the problem that the host-compiler
282still may need compile-time information from the target-only
283extension, like the import library of modules. One option is to copy
284the import-library source file into the repository of the host compiler:
285
286 # optionally, you can compile the import library:
287 # ~/cross-chicken/bin/arm-csc -O3 -d0 -s target-only-extension.import.scm
288 cp target-only-extension.import.scm ~/cross-chicken/lib/chicken/9
289
290=== Final notes
291
292Cross-development is a very tricky process - it often involves countless
293manual steps and it is very easy to forget an important detail or mix
294up target and host systems. Also, full 100% platform neutrality is
295hard to achieve. CHICKEN tries very hard to make this transparent, but
296at the price of considerable complexity in the code that manages
297extensions.
298
299
300----
301Previous: [[Deployment]]
302
303Next: [[Bugs and limitations]]
Trap